package com.maben.security.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt工具类
 */
@Component
@Slf4j
public class JwtUtils {
    // 从配置文件读取 JWT 密钥（必填，建议复杂字符串）
    @Value("${jwt.secret:NwJn37VOpvcQIw1c7hpTmlP/sQCPBVN8ZVYeSLc5r4c=}") // 可在 application.properties 中配置
    private String secret;

    // 过期时间（单位：毫秒，例如 10000 表示 10 秒）
    @Value("${jwt.expire:10000}")
    private long expire;

    /**
     * 生成 Token（基于用户名）
     */
    public String generateToken(String username) {
        // 构建 payload（自定义数据）
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", username); // 存储用户名
        // 生成符合 HS256 算法的密钥（自动校验密钥长度，不足会报错）
        byte[] keyBytes = secret.getBytes();
        Key signingKey = Keys.hmacShaKeyFor(keyBytes); // 替代直接使用 byte[]
        // 生成 Token（设置签发时间、过期时间、签名算法）
        return Jwts.builder()
                .setClaims(claims) // 自定义 payload 数据
                .setIssuedAt(new Date()) // 签发时间（当前时间）
                .setExpiration(new Date(System.currentTimeMillis() + expire)) // 过期时间（当前时间 + 有效期）
                .signWith(signingKey) // 签名算法（HS256）+ 密钥
                .compact(); // 生成 Token 字符串
    }

    /**
     * 验证 Token 有效性（签名 + 过期时间）
     */
    public boolean validateToken(String token) {
        try {
            // 解析 Token 并验证签名和过期时间
            Jwts.parserBuilder()
                    .setSigningKey(secret.getBytes()) // 使用相同的密钥验证签名
                    .build()
                    .parseClaimsJws(token); // 解析并验证
            return true; // 验证通过
        } catch (Exception e) {
            log.error("validateToken:{}", ExceptionUtils.getMessage(e));
            // 验证失败（签名错误、已过期等）
            return false;
        }
    }

    /**
     * 从 Token 中解析用户名
     */
    public String getUsernameFromToken(String token) {
        final Claims claims = Jwts.parserBuilder()
                .setSigningKey(secret.getBytes())
                .build()
                .parseClaimsJws(token)
                .getBody();
        return claims.get("username", String.class);
    }

    /**
     * 在需要获取姓名的地方（如 Service、Controller）调用
     */
    public String getCurrentUserRealName() {
        // 1. 获取当前认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw new RuntimeException("未登录");
        }

        // 2. 获取用户详情（CustomUserDetails）
        Object principal = authentication.getPrincipal();
        if (principal instanceof CustomUserDetails) {
            // 3. 从自定义 UserDetails 中获取真实姓名
            return ((CustomUserDetails) principal).getUsername();
        }

        // 匿名用户（未登录）
        throw new RuntimeException("未登录或用户信息错误");
    }
}